package game;

import static game.SelectJFrame.selectRole;

import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import card.Card;
import card.CardPileDaoImpl;
import card.CardType;
import player.Player;
import player.PlayerState;
import realCard.CardSha;
import realCard.CardShan;
import realCard.CardTao;
import realCard.CardWuZhongShengYou;
import realRole.RoleCaoCao;
import realRole.RoleGuoJia;
import realRole.RoleHuangGai;
import realRole.RoleLuXun;
import realRole.RoleLvMeng;
import realRole.RoleZhangFei;
import role.Role;
import skill.SkillType;

public class GameJFrame extends JFrame implements ActionListener {

	private Container container = null;

	/**管理出牌、结束、弃牌、发动技能、取消发动技能 和 发送四个按钮*/
	private JButton[] playerButton = new JButton[6];

	/**判断谁的回合*/
	private int turn = 0;

	/**游戏的的图标*/
	private JLabel gameLabel;

	/**集合嵌套集合
	   大集合中有两个小集合
	   小集合中装着每一个玩家当前要出的牌
	   0索引：自己
	   1索引：对手*/
	ArrayList<ArrayList<Card>> currentList = new ArrayList<>();

	/**集合嵌套集合
	   大集合中有两个小集合
	   小集合中装着每一个玩家的牌
	   0索引：自己
	   1索引：对手*/
	public ArrayList<ArrayList<Card>> playerList = new ArrayList<>();

	/**牌堆，装所有的牌*/
	private CardPileDaoImpl cardList = new CardPileDaoImpl(this);
	
	/**弃牌堆*/
	private ArrayList<Card> foldPile = new ArrayList<>();

	/**添加玩家*/
	private ArrayList<Player> playersArr = new ArrayList<>();

	/**两个玩家前方的时间提示
	   0索引：自己
	   1索引：对手*/
	private JTextField[] time = new JTextField[2];

	private JTextField tip;
	
	/**对局记录*/
	private JTextArea recordArea = new JTextArea();
	
	 /**用户操作，涉及多线程的知识*/
    private PlayerOperation po;

    boolean nextPlayer = false;

	public GameJFrame() {
		// 设置图标
		setIconImage(Toolkit.getDefaultToolkit().getImage("src/images/logo.png"));
		// 设置界面
		initJframe();
		// 初始化玩家
		initPlayer();
		// 添加组件
		initView();
		// 先展示界面再发牌，因为发牌里面有动画，界面不展示出来，动画无法展示
		this.setVisible(true);
		// 准备牌，洗牌，发牌
		new Thread(this::initCard).start();
		// 打牌之前的准备工作
		initGame();
	}

	/**初始化玩家（角色显示、技能、HP）*/
	public void initPlayer() {
		// 生成两个角色
		for (int i = 0; i < 2; i++) {

			// 角色初始化
			if (i == 0) {
				Role role = selectRole(i);
				Player player = new Player(null, null, role, this , i);
				playersArr.add(player);
				role.paintRole();
				role.setBounds(825, 500, 163, 175);
				container.add(role);
				container.setComponentZOrder(role, 0);
				container.repaint();
				//血槽
				player.getHP().rePaintHP();
				player.getHP().setBounds(830, 580, 22, 22 * player.getSelectedRole().getMaximumHP());
				container.add(player.getHP());
				container.setComponentZOrder(player.getHP(), 0);
				container.repaint();
			} else {
				Role role = selectRole(i);
				Player player = new Player(null, null, role, this, i);
				playersArr.add(player);
				role.paintRole();
				role.setBounds(425, 45, 214, 182);
				container.add(role);
				container.setComponentZOrder(role, 0);
				container.repaint();
				//血槽
				player.getHP().rePaintHP();
				player.getHP().setBounds(430, 130, 22, 22 * player.getSelectedRole().getMaximumHP());
				container.add(player.getHP());
				container.setComponentZOrder(player.getHP(), 0);
				container.repaint();
			}

		}
	}

	/**初始化牌*/
	public void initCard() {
		for (Card card: cardList.getList()) {
			setCardLocation(card);
		}
		// 创建两个集合来装两个玩家的牌，并把两个小集合放到大集合中方便管理 //就是手牌区的初始化
		ArrayList<Card> player0 = new ArrayList<>();
		ArrayList<Card> player1 = new ArrayList<>();
		playersArr.get(0).setHandsCard(player0);
		playersArr.get(1).setHandsCard(player1);
		for (int i = 0; i < 8; i++) {
			// 获得当前遍历的牌
			Card card = cardList.drawCard();
			// 把牌置于顶层
			container.setComponentZOrder(card, 0);

			// 给两个玩家发牌
			if (i % 2 == 0) {
				// 给自己发牌
				card.setCanClick(true);
				player0.add(card);
				Common.move(card, card.getLocation(), new Point(250 + i * 45, 530));
				// 自己的牌是正面的
				card.turnFront();
			} else if (i % 2 == 1) {
				// 给对手发牌
				player1.add(card);
				Common.move(card, card.getLocation(), new Point(300,50));
				card.setVisible(true);
			}
			// 把两个装牌的小集合放入大集合中管理,并使牌堆移除所有已经发出的牌
			playerList.add(player0);
			playerList.add(player1);
		}
	}

	/**辅助方法*/
	public void setCardLocation(Card card) {
		card.setLocation(30, 200);
		container.add(card);
		container.setComponentZOrder(card, 0);
	}
	
	public void initGame() {
		//创建两个集合用来装两个玩家准备要出的牌
        for (int i = 0; i < 2; i++) {
            ArrayList<Card> list = new ArrayList<>();
            //添加到大集合中方便管理
            currentList.add(list);
        }
        //倒计时10秒
        po = new PlayerOperation(this, 0);
        //开启倒计时
        po.start();
	}

	/**添加组件*/
	public void initView() {

		// 创建出牌的按钮
		JButton outCardBut = new JButton("出牌");
		outCardBut.setBounds(350, 430, 80, 25);
		outCardBut.setOpaque(false);
		outCardBut.addActionListener(this);
		outCardBut.setVisible(false);// 改false
		playerButton[0] = outCardBut;
		container.add(outCardBut);
		container.setComponentZOrder(outCardBut, 0);

		// 创建结束的按钮
		JButton noCardBut = new JButton("结束");
		noCardBut.setBounds(450, 430, 80, 25);
		noCardBut.addActionListener(this);
		noCardBut.setVisible(false);// 改false
		playerButton[1] = noCardBut;
		container.add(noCardBut);
		container.setComponentZOrder(noCardBut, 0);
		
		// 创建弃牌的按钮
		JButton foldButton = new JButton("弃牌");
		foldButton.setBounds(450, 430, 80, 25);
		foldButton.setOpaque(false);
		foldButton.addActionListener(this);
		foldButton.setVisible(false);//要为false
		playerButton[2] = foldButton;
		container.add(foldButton);
		container.setComponentZOrder(foldButton, 0);
		
		//技能触发按钮
		JButton skillEffectButton = new JButton("触发");
		skillEffectButton.setBounds(350, 430, 80, 25);
		skillEffectButton.setOpaque(false);
		skillEffectButton.addActionListener(this);
		skillEffectButton.setVisible(false);
		playerButton[3] = skillEffectButton;
		container.add(skillEffectButton);
		container.setComponentZOrder(skillEffectButton, 0);
		
		//取消触发按钮
		JButton cancelButton = new JButton("取消");
		cancelButton.setBounds(450, 430, 80, 25);
		cancelButton.setOpaque(false);
		cancelButton.addActionListener(this);
		cancelButton.setVisible(false);
		playerButton[4] = cancelButton;
		container.add(cancelButton);
		container.setComponentZOrder(cancelButton, 0);
		
		// 创建两个玩家前方的提示文字：倒计时
		// 每个玩家一个
		// 左边的电脑玩家是1
		// 中间的自己是0
		for (int i = 0; i < 2; i++) {
			time[i] = new JTextField("倒计时:");
			time[i].setEditable(false);
			time[i].setVisible(false);// 改false
			container.add(time[i]);
			container.setComponentZOrder(time[i], 0);
		}
		time[0].setBounds(400, 400, 80, 25);
		time[1].setBounds(310, 200, 80, 25);
		
		//创建玩家前的提示：
		tip = new JTextField("");
		tip.setFont(new Font("宋体", Font.BOLD, 20));
		tip.setForeground(Color.red);
		tip.setEditable(false);
		tip.setVisible(false);
		tip.setBackground(Color.gray);
		tip.setOpaque(false);
		tip.setBorder(null);
		container.add(tip);
		container.setComponentZOrder(tip, 0);
		tip.setBounds(370,500,140,25);

		//文字
		JButton skillBut = new JButton(playersArr.get(0).getSelectedRole().getSkill().getName());
		skillBut.setVisible(true);
		skillBut.setOpaque(false);
		skillBut.addActionListener(this);
		skillBut.setBounds(830, 680, 70, 20);
		skillBut.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(playersArr.get(0).isMyRound() && time[0].isVisible()) {
					 if(playersArr.get(0).getSelectedRole().getSkill().getType() == SkillType.WHEN_BUTTON_CLICKED){
							playersArr.get(0).getSelectedRole().getSkill().effect();
							recordArea.append(playersArr.get(0).getSelectedRole().getName() + " 使用了 " + playersArr.get(0).getSelectedRole().getSkill().getName() + "\n");
						}
				}
			}
		});
		container.add(skillBut);
		container.setComponentZOrder(skillBut, 0);
	}

	/**监听*/
	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == playerButton[0] && playerList.get(0).size() != 0) {
			
			//定义：我的手牌、要出的牌、是否还能出杀和选中的玩家及其角色
			ArrayList<Card> myHandsCard = playerList.get(0);
			Card removeCard = null;
			Player selectedPlayer = null;
			Role selectedRole = null;
			
			//找到要出的牌
			for (Card card : myHandsCard) {
				if (card.isClicked()) {
					removeCard = card;
					break;
				}
			}
			//找到要作用的角色
			if(removeCard.getEffect() == PlayerState.EQUIPPED) {
				//装备牌的话，目标肯定就是自己
				selectedRole = playersArr.get(0).getSelectedRole();
				selectedPlayer = playersArr.get(0);
			}else if(removeCard.getEffect() == PlayerState.PUSH_THE_LIMIT) {
				//解除限制的牌，这个也是固定目标是自己
				selectedRole = playersArr.get(0).getSelectedRole();
				selectedPlayer = playersArr.get(0);
			}else if(removeCard.getEffect() == PlayerState.GET_TREATED) {
				//双人对局的话：桃的目标也肯定是自己
				selectedRole = playersArr.get(0).getSelectedRole();
				selectedPlayer = playersArr.get(0);
			}else if((removeCard.getClass() == CardShan.class) && (playersArr.get(0).getState() == PlayerState.BEHURT)) {
				//被杀状态下，闪也是自己（除去被伤状态）
				selectedRole = playersArr.get(0).getSelectedRole();
				selectedPlayer = playersArr.get(0);
			}else if(removeCard.getType() == CardType.TIP) {
				//锦囊牌：双人的话作用对象是自己
				System.out.println("你选了锦囊牌");
				selectedRole = playersArr.get(0).getSelectedRole();
				selectedPlayer = playersArr.get(0);
			}else { //其他的牌就被点击的角色为目标
				for(Player player : playersArr) {
					if(player.getSelectedRole().isSelected()) {
						selectedRole = player.getSelectedRole();
						selectedPlayer = player;
						player.getSelectedRole().changeIsSelected();
						break;
					}
				}
			}
			
			if((removeCard != null) && (selectedRole != null)) {
				if(removeCard.getClass() == CardSha.class) {
					//如果玩家出的是杀
					if(!(selectedPlayer == playersArr.get(0))) {
						//选中的玩家并不是自己
						if(!playersArr.get(0).isSendCardShaFlag()) {
							selectedPlayer.setState(removeCard.getEffect());
							//使得目标玩家进入卡牌的作用状态
							Common.moveHandsCard(removeCard, 0, myHandsCard);
							Common.rePositon(this, playerList.get(0), 0);
							recordArea.append(playersArr.get(0).getSelectedRole().getName() + " 对 " + selectedRole.getName() + " 使用了 " + removeCard.getName() + "\n");
							//加入弃牌堆
							foldPile.add(removeCard);
							playersArr.get(0).setSendCardShaFlag(true);
							time[0].setVisible(false);
							this.nextPlayer = true;
							this.turn = 1;
						}
					}
				}else if((removeCard.getClass() == CardShan.class) && (playersArr.get(0).getState() == PlayerState.BEHURT)) {
					//使得目标玩家进入卡牌的作用状态
					selectedPlayer.setState(removeCard.getEffect());
					Common.moveHandsCard(removeCard, 0, myHandsCard);
					Common.rePositon(this, playerList.get(0), 0);
					recordArea.append(playersArr.get(0).getSelectedRole().getName()+"回应了闪"+ "\n");
					//加入弃牌堆
					foldPile.add(removeCard);
					time[0].setVisible(false);
					this.nextPlayer = true;
				}else if(removeCard.getClass() == CardTao.class) {
					
					Common.sendCardTao(playersArr.get(0), removeCard, null, null);
					Common.rePositon(this, myHandsCard, 0);
					this.recordArea.append(playersArr.get(0).getSelectedRole().getName() + " 对 " + selectedPlayer.getSelectedRole().getName() +
						" 使用了 " + removeCard.getName() + "，目前" + selectedPlayer.getSelectedRole().getName() + "的生命为：" + selectedPlayer.getHP().getActualHP() + "\n");
					foldPile.add(removeCard);
				}else if(removeCard.getType() == CardType.WEAPON) {
					//装备牌
					playersArr.get(0).getEquipment()[0] = removeCard;
					//武器放在0位置
					playersArr.get(0).setState(removeCard.getEffect());
					removeCard.beEquiped();
					if(removeCard.getEffect() == PlayerState.PUSH_THE_LIMIT){
						removeCard.effect(selectedPlayer);
					}
					Common.moveHandsCard(removeCard, 0, myHandsCard);
					Common.rePositon(this, playerList.get(0), 0);
					this.recordArea.append(playersArr.get(0).getSelectedRole().getName() + " 装备了 " + removeCard.getName() + "\n");
					foldPile.add(removeCard);
				}else if(removeCard.getType() == CardType.TIP) {
					System.out.println("点击了锦囊牌");
					removeCard.effect(selectedPlayer);
					Common.moveHandsCard(removeCard, 0, myHandsCard);
					if(removeCard.getClass() != CardWuZhongShengYou.class) {
						Common.rePositon(this, playerList.get(0), 0);
					}
					this.recordArea.append(playersArr.get(0).getSelectedRole().getName() + " 使用了 " + removeCard.getName() + "\n");
					foldPile.add(removeCard);
					if(removeCard.getEffect() == PlayerState.BEHURT) {
						time[0].setVisible(false);
						this.nextPlayer = true;
						this.turn = 1;
					}
				}			
			}
		}else if(e.getSource() == playerButton[1]) {
			time[0].setVisible(true);
			time[0].setText("取消");
			//赢藏文本提示
            time[0].setVisible(false);
            //下一个玩家可玩
            this.nextPlayer = true;
		}else if(e.getSource() == playerButton[2]) {
			//得到处于该回合的玩家
			Player player = playersArr.get(0);
			ArrayList<Card> handsCard = player.getHandsCard();
			ArrayList<Card> removeCardList = new ArrayList<>();
			for (Card card : handsCard) {
				if(card.isClicked()) {
					removeCardList.add(card);
				}
			}
			//移动要移除的牌，并且从玩家手牌中移除,注意：移除后剩余牌等于体力值
			if(handsCard.size() - removeCardList.size() == player.getHP().getActualHP()) {
				for (Card removeCard : removeCardList) {
					Common.moveHandsCard(removeCard, 0, handsCard);
				}
				handsCard.removeAll(removeCardList);
				Common.rePositon(this, handsCard, 0);
				foldPile.addAll(removeCardList);
				//下一个玩家可玩
	            this.nextPlayer = true;
			}	
		}else if(e.getSource() == playerButton[3]) {
			playersArr.get(0).getSelectedRole().getSkill().effect();
			this.recordArea.append(playersArr.get(0).getSelectedRole().getName() + " 发动了 " + playersArr.get(0).getSelectedRole().getSkill().getName() + "\n");
			//测试
			time[0].setVisible(false);
			this.nextPlayer = true;
		}else if(e.getSource() == playerButton[4]) {
			time[0].setVisible(true);
			time[0].setText("取消");
			//赢藏文本提示
            time[0].setVisible(false);
            //下一个玩家可玩
            this.nextPlayer = true;
		}
	}

	/**设置界面*/
	public void initJframe() {
		// 设置标题
		this.setTitle("三国杀");
		// 设置大小
		this.setSize(1024, 768);
		// 设置关闭模式
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 设置窗口无法进行调节
		this.setResizable(false);
		// 界面居中
		this.setLocationRelativeTo(null);
		// 获取界面中的隐藏容器，以后直接用无需再次调用方法获取了
		container = this.getContentPane();
		// 取消内部默认的居中放置
		container.setLayout(null);
		// 背景设置
		JLabel background = new JLabel(new ImageIcon("src/images/background.jpg"));
		background.setBounds(0, 0, 1024, 768);
		background.setOpaque(false);
		container.add(background);
		JLabel controlBackground = new JLabel(new ImageIcon("src/images/background_Control.jpg"));
		controlBackground.setBounds(0, 470, 909, 260);
		JLabel equipBackground = new JLabel(new ImageIcon("src/images/background_eq.jpg"));
		equipBackground.setBounds(20, 510, 221, 188);
		JLabel headBorderBackground = new JLabel(new ImageIcon("src/images/headborder.png"));
		headBorderBackground.setBounds(800, 475, 214, 220);
		JLabel rivalHeadBorderBackground = new JLabel(new ImageIcon("src/images/headborder.png"));
		rivalHeadBorderBackground.setBounds(400, 20, 214, 220);
		container.add(controlBackground);
		container.add(equipBackground);
		container.add(headBorderBackground);
		container.add(rivalHeadBorderBackground);
		container.setComponentZOrder(controlBackground, 0);
		container.setComponentZOrder(equipBackground, 0);
		container.setComponentZOrder(headBorderBackground, 0);
		container.setComponentZOrder(rivalHeadBorderBackground, 0);

		// 聊天窗口
		JPanel chessPanel = new JPanel();
		chessPanel.setBounds(790, 195, 230, 230);
		chessPanel.setBackground(Color.LIGHT_GRAY);
		container.add(chessPanel);
		container.setComponentZOrder(chessPanel, 0);
		JLabel chessBackground = new JLabel(new ImageIcon("src/images/113406byuftiprnbusxk2q.jpg"));
		chessBackground.setBounds(789, 197, 231, 231);
		container.add(chessBackground);
		container.setComponentZOrder(chessBackground, 0);
		Font f1 = new Font("新宋体", Font.PLAIN, 12);

		//聊天内容
		JTextArea chessArea = new JTextArea();
		chessArea.setBounds(792, 200, 210, 200);
		// 不可修改其中内容
		chessArea.setEditable(false);
		// 聊天 -- 滑动组件
		JScrollPane sp = new JScrollPane();
		sp.setViewportView(chessArea);
		sp.setBounds(792, 200, 213, 200);
		sp.setOpaque(false);
		sp.getViewport().setOpaque(false);
		chessPanel.add(sp);
		container.setComponentZOrder(sp, 0);
		//聊天行
		JTextField chessInput = new JTextField(20);
		chessInput.setBounds(792, 404, 150, 20);
		chessInput.setFont(f1);
		chessInput.setText("来友好地交流吧！");
		chessPanel.add(chessInput);
		container.setComponentZOrder(chessInput, 0);
		//发送按钮
		JButton chessButton = new JButton("发送");
		chessButton.setBounds(947, 404, 58, 20);
		//点击触发--方式
		chessButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String words = chessInput.getText();
				if (!"".equals(words)) {
					chessInput.setText("");
					chessArea.append(playersArr.get(0).getSelectedRole().getName() + "：" + words + "\n");// 输出到chessArea中
				}
			}
		});
		chessButton.setOpaque(false);
		chessPanel.add(chessButton);
		chessButton.setBackground(Color.green);
		container.setComponentZOrder(chessButton, 0);
		// 对局记录
		JPanel recordPanel = new JPanel();
		recordPanel.setBounds(790, 53, 230, 140);
		recordPanel.setBackground(Color.LIGHT_GRAY);
		container.add(recordPanel);
		container.setComponentZOrder(recordPanel, 0);
		/**/
		JLabel recordBackground = new JLabel(new ImageIcon("src/images/113406byuftiprnbusxk2q.jpg"));
		recordBackground.setBounds(789, 53, 231, 141);
		container.add(recordBackground);
		container.setComponentZOrder(recordBackground, 0);
		//对局内容
		recordArea.setBounds(792, 53, 210, 140);
		recordArea.setEditable(false);
		// 对局 -- 滑动组件
		JScrollPane recordSp = new JScrollPane();
		recordSp.setViewportView(recordArea);
		recordSp.setBounds(792, 55, 213, 138);
		recordSp.setOpaque(false);
		recordSp.getViewport().setOpaque(false);
		chessPanel.add(recordSp);
		container.setComponentZOrder(recordSp, 0);
		//武器区
		JPanel armsPanel = new JPanel();
		armsPanel.setBounds(65,515,170,40);
		armsPanel.setBackground(Color.LIGHT_GRAY);
		armsPanel.setVisible(true);
		
	}
	public Role selectRole(int i)
	{
		switch (selectRole.get(i))
		{
			case "caocao":
				return new RoleCaoCao(this);
			case "guojia":
				return new RoleGuoJia(this);
			case "huanggai":
				return new RoleHuangGai(this);
			case "luxun":
				return new RoleLuXun(this);
			case "zhangfei":
				return new RoleZhangFei(this);
			case "lvmeng":
				return new RoleLvMeng(this);
			default:
				return null;
		}
	}

	public Container getContainer() {
		return container;
	}

	public void setContainer(Container container) {
		this.container = container;
	}

	public JButton[] getPlayerButton() {
		return playerButton;
	}

	public void setPlayerButton(JButton[] playerButton) {
		this.playerButton = playerButton;
	}

	public ArrayList<Card> getCardList() {
		return cardList.getList();
	}
	public ArrayList<Card> getFoldPile() {
		return foldPile;
	}

	public void setFoldPile(ArrayList<Card> foldPile) {
		this.foldPile = foldPile;
	}

	public ArrayList<Player> getPlayersArr() {
		return playersArr;
	}

	public void setPlayersArr(ArrayList<Player> playersArr) {
		this.playersArr = playersArr;
	}

	public JTextField[] getTime() {
		return time;
	}

	public void setTime(JTextField[] time) {
		this.time = time;
	}

	public JTextField getTip() {
		return tip;
	}

	public void setTip(JTextField tip) {
		this.tip = tip;
	}

	public JTextArea getRecordArea() {
		return recordArea;
	}

	public void setRecordArea(JTextArea recordArea) {
		this.recordArea = recordArea;
	}

	public int getTurn() {
		return turn;
	}

	public void setTurn(int turn) {
		this.turn = turn;
	}

	public JLabel getGameLabel() {
		return gameLabel;
	}

	public void setGameLabel(JLabel gameLabel) {
		this.gameLabel = gameLabel;
	}

	public PlayerOperation getPo() {
		return po;
	}

	public void setPo(PlayerOperation po) {
		this.po = po;
	}
	
	
	/*getter and setter*/
	

}
